
#include "snes9x.h"
#include "memmap.h"
#include "debug.h"
#include "cpuexec.h"
#include "ppu.h"
#include "snapshot.h"
//#include "apu.h"
#include "display.h"
#include "gfx.h"
#include "soundux.h"


uint32 joypads [5] = {0};
int NumControllers = 1;

#ifdef JOYSTICK_SUPPORT
bool8 joystick_has_four_buttons = FALSE;
bool8 joystick_has_six_buttons = FALSE;
bool8 joystick_has_eight_buttons = FALSE;

#ifdef SIDEWINDER_SUPPORT
void InitSidewinders ();
int ReadSidewinders ();
bool8 alternate_sidewinder_mapping = FALSE;
#endif
void InitJoysticks ();
void ReadJoysticks ();
#endif

extern wchar_t srmname[256];

//void InitTimer ();

int MAX_ROM_SIZE=0x800000;

wchar_t *rom_filename = NULL;
wchar_t *snapshot_filename = NULL;

void OutOfMemory ()
{
/*    fprintf (stderr, "\
Snes9X: Memory allocation failure - not enough RAM/virtual memory available.\n\
        S9xExiting...\n");
    Memory.Deinit ();
    S9xDeinitAPU ();
    
    exit (1);*/
}

void S9xParseArg (char **argv, int &i, int argc)
{	
}

int dosmain (wchar_t *fname)
{
    Settings.JoystickEnabled = FALSE;
    Settings.SoundPlaybackRate = 4;
    Settings.Stereo = FALSE;//TRUE;
    Settings.SoundBufferSize = 0;
    Settings.CyclesPercentage = 100;
    Settings.DisableSoundEcho = FALSE;
    Settings.APUEnabled = Settings.NextAPUEnabled = TRUE;
    Settings.H_Max = SNES_CYCLES_PER_SCANLINE;
    Settings.ShutdownMaster = TRUE;
    Settings.FrameTimePAL = 20000;
    Settings.FrameTimeNTSC = 16667;
    Settings.FrameTime = Settings.FrameTimeNTSC;
    Settings.DisableSampleCaching = FALSE;
    Settings.DisableMasterVolume = FALSE;
    Settings.Mouse = FALSE;
    Settings.SuperScope = FALSE;
    Settings.MultiPlayer5 = FALSE;
    Settings.ControllerOption = SNES_JOYPAD;   
    Settings.SupportHiRes = FALSE;
    Settings.NetPlay = FALSE;
    Settings.ServerName [0] = 0;
    Settings.ThreadSound = FALSE;
    Settings.AutoSaveDelay = 30;
    Settings.ApplyCheats = TRUE;
    Settings.TurboMode = FALSE;
    Settings.TurboSkipFrames = 20;
    
	rom_filename = fname;
	
	Settings.Mute=1;
    Settings.TraceSoundDSP=0;
    Settings.APUEnabled=0;
    //add2 ??????????
    Settings.SoundPlaybackRate = 0;//4;
    Settings.Stereo = FALSE;//TRUE;
    Settings.SoundBufferSize = 0;
    //Settings.CyclesPercentage = 100;
    Settings.DisableSoundEcho = TRUE;//FALSE;
    Settings.APUEnabled = Settings.NextAPUEnabled = FALSE;//TRUE;
//////////

   
    Settings.HBlankStart = (256 * Settings.H_Max) / SNES_HCOUNTER_MAX;


    if (!Memory.Init () /*|| !S9xInitAPU()*/){
	  OutOfMemory ();
	  return 2;
	}

    uint32 saved_flags = CPU.Flags;

#ifdef GFX_MULTI_FORMAT
    S9xSetRenderPixelFormat (RGB565);
#endif

    //if (rom_filename)
    //{
	if (!Memory.LoadROM (rom_filename))
	{
		return 3;
	}
	Memory.LoadSRAM (srmname);
    //}
    //else
    //{
	//S9xReset ();
	//Settings.Paused |= 2;
    //}
    CPU.Flags = saved_flags;

    S9xInitInputDevices ();

    S9xInitDisplay ();
    if (!S9xGraphicsInit ()){
	  OutOfMemory ();
	  return 4;
	}

    if (!Settings.APUEnabled)
   	  S9xSetSoundMute (TRUE);

    if (snapshot_filename)
    {
	int Flags = CPU.Flags & (DEBUG_MODE_FLAG | TRACE_FLAG);
	//if (!S9xLoadSnapshot (snapshot_filename))
//	    exit (1);
	CPU.Flags |= Flags;
    }

    //S9xGraphicsMode ();

    //sprintf (String, "\"%s\" %s: %s", Memory.ROMName, TITLE, VERSION);
    //S9xSetTitle (String);
    
//#ifdef JOYSTICK_SUPPORT
//    uint32 JoypadSkip = 0;
//#endif

    //InitTimer ();
    //if (!Settings.APUEnabled)  //?????????
  	//  S9xSetSoundMute (FALSE);


    return (0);
}

void S9xAutoSaveSRAM ()
{
    //Memory.SaveSRAM (S9xGetSRAMFilename ());
}

void S9xExit ()
{
    S9xGraphicsDeinit();
    S9xDeinitDisplay ();
    Memory.SaveSRAM (srmname);
    Memory.Deinit ();
    //S9xDeinitAPU ();
}



const char *GetHomeDirectory ()
{
    return (".");
}

STREAM S9xOpenSnapshotFile (const wchar_t *fname, bool8 read_only)
{
  STREAM file;
    if (read_only)
    {
      if ((file = fopen(fname,WA_Read,0x180))!=-1)
	    return file;
    }
    else
    {
      if ((file = fopen (fname,0x204,0x180))!=-1)
              return file;
    }
    return -1;
}


void S9xCloseSnapshotFile (STREAM file)
{
    fclose (file);
}

bool8 S9xInitUpdate ()
{
    return (TRUE);
}

bool8 S9xDeinitUpdate (int Width, int Height, bool8 sixteen_bit)
{
    S9xPutImage (Width, Height);

    return (TRUE);
}



uint32 S9xReadJoypad (int which1)
{
    if (which1 < NumControllers)
    {
      uint32 joyp = joypads [which1];
     // joypads[which1] = 0;
      return (0x80000000 | joyp);
    }
    return (0);
}
